<?php
/**
 * Created by PhpStorm.
 * User: jjj
 * Date: 2017/8/31
 * Time: 10:33
 */

namespace app\common\lib\pay;

require_once __DIR__.'/../wxpay/WxPay.Api.php';

use Endroid\QrCode\QrCode;
use \Exception;
use NativePay;
use think\Log;
use WxPayApi;
use WxPayBizPayUrl;
use WxPayUnifiedOrder;


class WeixinPay implements IPay
{
    // 应用ID
    private static $AppId = [
        self::TRADE_TYPE_APP => 'wxcba36d37fe539203',
        self::TRADE_TYPE_WAP => 'wx071715cfd51ed8cc',
        self::TRADE_TYPE_PC => 'wx071715cfd51ed8cc',
    ];

    private $notify_url; // 通知url
    private $certificate; // 证书文件路径

    private function __construct()
    {
        $this->notify_url = config('server.host') . '/callback/pay/weixin';
        $this->certificate = __DIR__.'/../wxpay/cert/apiclient_certs.pem';
    }


    const CODE_SUCCESS = 'SUCCESS';
    const CODE_FAIL = 'FAIL';

    // 支付类型
    const TRADE_TYPE_APP = 1;
    const TRADE_TYPE_WAP = 2;
    const TRADE_TYPE_PC = 3;
    private static $TradeTypes = [
        self::TRADE_TYPE_APP => 'APP',
        self::TRADE_TYPE_WAP => 'JSAPI',
        self::TRADE_TYPE_PC => 'NATIVE',
    ];

    private static $instance = null;
    /**
     * @return static
     */
    public static function getInstance() {
        if (empty(self::$instance)) {
            self::$instance = new static();
        }
        return self::$instance;
    }

    public static function getAppId($client_type) {
        return self::$AppId[$client_type] ?? null;
    }

    /**
     * 公共方法
     */
    /**
     * 下订单
     *
     * @param $out_trade_no string 订单号
     * @param $total_fee float 支付总金额
     * @param $body string 商品描述
     * @param $client_type integer 支付类型，比如 1-APP、2-PC、3-微信页面
     * @param $client_ip string 支付的客户端实际IP
     * @param $detail string
     * @param string $ext
     * @return array|false
     * @throws Exception
     */
    public function unifiedOrder(
        $out_trade_no, $total_fee, $body, $client_type, $client_ip, $detail = '', $ext = null
    ) {
        $total_fee = intval(100 * floatval($total_fee));
        if ($total_fee <= 0) throw new Exception('金额不正确',1);
        $now = time();

        if (!isset(self::$TradeTypes[$client_type])) $client_type = self::TRADE_TYPE_APP;

        $input = new WxPayUnifiedOrder();
        $input->SetOut_trade_no($out_trade_no);
        $input->SetTotal_fee($total_fee);
        $input->SetBody($body);
        $input->SetSpbill_create_ip($client_ip);
        $input->SetDetail($detail);
        $input->SetTime_start(date("YmdHis", $now));
        $input->SetTime_expire(date("YmdHis", $now + 600));
        $input->SetTrade_type(self::$TradeTypes[$client_type]);
        $input->SetNotify_url($this->notify_url);
        $input->SetAppid(self::$AppId[$client_type]);

        if (self::TRADE_TYPE_PC == $client_type) {
            require_once __DIR__.'/../wxpay/WxPay.NativePay.php';
            $native = new NativePay();

            $input->SetProduct_id($out_trade_no);
            $result = $native->GetPayUrl($input);
            if (empty($result['code_url'])) {
                throw new Exception('获取二维码url失败');
            }

            $QRCode = new QrCode($result['code_url']);
            $QRCode->setSize(100);
            header('Content-Type: '.$QRCode->getContentType());
            $result['img_data'] = $QRCode->writeDataUri();

        } elseif (self::TRADE_TYPE_WAP == $client_type) {

            if ($ext) {
                $input->SetOpenid($ext);
                $result = WxPayApi::unifiedOrder($input);
                require_once __DIR__.'/../wxpay/WxPay.JsApiPay.php';
                $jsApi = new \JsApiPay();
                $result = $jsApi->GetJsApiParameters($result);
            } else {
                $scene_info = [
                    'h5_info' => [
                        'type' => 'Wap',
                        'wap_url' => 'http://wechat.zqcj.net.cn',
                        'wap_name' => '掌乾财经',
                    ]
                ];
                $input->SetScene_info($scene_info);
                $result = WxPayApi::unifiedOrder($input);
            }


        } else {

            $result = WxPayApi::unifiedOrder($input);
        }

        return $result;
    }


    /**
     * 获取字段key，方便客户端调用
     *
     * @return string
     */
    function getKey()
    {
        return 'weixinpay';
    }

}